package io.youngledo.usb.ui;

import io.youngledo.usb.util.DialogUtils;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.scene.control.*;
import javafx.scene.layout.*;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;

/// 异常列表对话框
///
/// 显示所有捕获的异常，点击可查看详细堆栈
/// 使用 Alert 架构以保持样式一致性
public class ExceptionListDialog extends Alert {

    private final ListView<ExceptionItem> exceptionListView;
    private final ObservableList<ExceptionItem> exceptionItems;
    private static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern("HH:mm:ss");
    private Runnable onClearCallback; // 清空回调

    public ExceptionListDialog() {
        super(AlertType.NONE);

        setTitle("异常列表");
        setHeaderText(null);

        exceptionItems = FXCollections.observableArrayList();
        exceptionListView = new ListView<>(exceptionItems);
        exceptionListView.getStyleClass().add("exception-list-view"); // 添加特殊样式类
        exceptionListView.setCellFactory(lv -> new ExceptionCell());

        // 双击查看详情
        exceptionListView.setOnMouseClicked(event -> {
            if (event.getClickCount() == 2) {
                ExceptionItem selected = exceptionListView.getSelectionModel().getSelectedItem();
                if (selected != null) {
                    ExceptionDialog.show(selected.getTitle(), selected.getMessage(), selected.getThrowable());
                }
            }
        });

        // 顶部工具栏
        HBox toolbar = new HBox();
        Button clearButton = new Button("清空列表");
        clearButton.setOnAction(e -> clearExceptions());
        toolbar.getChildren().addAll(clearButton);

        // 底部说明
        Label hintLabel = new Label("💡双击列表项查看详细异常堆栈");
        hintLabel.getStyleClass().add("exception-hint-label");
        hintLabel.setPadding(new Insets(5));

        VBox content = new VBox(5);
        content.getChildren().addAll(toolbar, exceptionListView, hintLabel);
        VBox.setVgrow(exceptionListView, Priority.ALWAYS);

        getDialogPane().setContent(content);
        getDialogPane().setPrefWidth(700);
        getDialogPane().setPrefHeight(500);

        // 只保留关闭按钮
        ButtonType closeButton = new ButtonType("关闭", ButtonBar.ButtonData.CANCEL_CLOSE);
        getButtonTypes().setAll(closeButton);

        // 应用扁平化样式
        DialogUtils.applyFlatStyle(this);
    }

    /// 添加异常
    ///
    public void addException(String title, String message, Throwable throwable) {
        ExceptionItem item = new ExceptionItem(title, message, throwable);
        exceptionItems.addFirst(item); // 最新的在最前面
    }

    /// 清空异常列表
    ///
    public void clearExceptions() {
        exceptionItems.clear();
        // 调用清空回调
        if (onClearCallback != null) {
            onClearCallback.run();
        }
    }

    /// 设置清空回调
    ///
    public void setOnClearCallback(Runnable callback) {
        this.onClearCallback = callback;
    }

    /// 获取异常数量
    ///
    public int getExceptionCount() {
        return exceptionItems.size();
    }

    /// 显示对话框
    ///
    public void showDialog() {
        showAndWait();
    }

    /// 异常项数据类
    ///
    public static class ExceptionItem {
        private final String title;
        private final String message;
        private final Throwable throwable;
        private final LocalDateTime timestamp;

        public ExceptionItem(String title, String message, Throwable throwable) {
            this.title = title;
            this.message = message;
            this.throwable = throwable;
            this.timestamp = LocalDateTime.now();
        }

        public String getTitle() {
            return title;
        }

        public String getMessage() {
            return message;
        }

        public Throwable getThrowable() {
            return throwable;
        }

        public LocalDateTime getTimestamp() {
            return timestamp;
        }
    }

    /// 异常列表单元格
    ///
    private static class ExceptionCell extends ListCell<ExceptionItem> {
        private final VBox container = new VBox(3);
        private final Label titleLabel = new Label();
        private final Label timeLabel = new Label();
        private final Label messageLabel = new Label();

        public ExceptionCell() {
            // 设置固定样式类
            titleLabel.getStyleClass().add("exception-title-label");
            timeLabel.getStyleClass().add("exception-time-label");
            messageLabel.getStyleClass().add("exception-message-label");
            messageLabel.setWrapText(true);

            HBox titleRow = new HBox(10);
            Region spacer = new Region();
            HBox.setHgrow(spacer, Priority.ALWAYS);
            titleRow.getChildren().addAll(titleLabel, spacer, timeLabel);

            container.getChildren().addAll(titleRow, messageLabel);
        }

        @Override
        protected void updateItem(ExceptionItem item, boolean empty) {
            super.updateItem(item, empty);

            if (empty || item == null) {
                setGraphic(null);
                setText(null);
                return;
            }

            // 更新内容
            titleLabel.setText(item.getTitle());
            timeLabel.setText(item.getTimestamp().format(TIME_FORMATTER));
            messageLabel.setText(item.getMessage());

            // 根据选中状态设置容器样式类
            container.getStyleClass().removeAll("exception-item", "exception-item-selected");
            if (isSelected()) {
                container.getStyleClass().add("exception-item-selected");
            } else {
                container.getStyleClass().add("exception-item");
            }

            setGraphic(container);
        }
    }
}
